SpringSecurity 整合 JWT+Oauth2 认证实战

您所在的位置:网站首页 spring boot jwt 认证 SpringSecurity 整合 JWT+Oauth2 认证实战

SpringSecurity 整合 JWT+Oauth2 认证实战

2023-03-28 19:49| 来源: 网络整理| 查看: 265

OAuth2是什么

简单来说,就是一种授权认证;一种针对开放系统间授权,分布式访问(单点登录)和现代微服务安全的解决方案;这种解决方案为我们提供了一种思路,但具体的实现我们要自己书写(就好比给我们一个接口)

所能解决的问题:开放系统键授权,分布式访问(单点登录)和 现代微服务安全

项目依赖:

org.springframework.security.oauth spring-security-oauth2 2.2.6.RELEASE org.springframework.security spring-security-jwt 1.1.0.RELEASE org.springframework.boot spring-boot-starter-security

一:创建所需要的User类,Menu权限类,WebUtils响应工具类(用于异常处理器中),SysResult响应数据工具类 代码如下:

User类

package com.jt.pojo; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; import java.util.Date; /** * 用户表(User)实体类 * * @author */ @Data @AllArgsConstructor @NoArgsConstructor @TableName("sys_user") public class User implements Serializable { private static final long serialVersionUID = -40356785423868312L; /** * 主键 */ @TableId private Long id; /** * 用户名 */ private String userName; /** * 昵称 */ private String nickName; /** * 密码 */ private String password; /** * 账号状态(0正常 1停用) */ private String status; /** * 邮箱 */ private String email; /** * 手机号 */ private String phonenumber; /** * 用户性别(0男,1女,2未知) */ private String sex; /** * 头像 */ private String avatar; /** * 用户类型(0管理员,1普通用户) */ private String userType; /** * 创建人的用户id */ private Long createBy; /** * 创建时间 */ private Date createTime; /** * 更新人 */ private Long updateBy; /** * 更新时间 */ private Date updateTime; /** * 删除标志(0代表未删除,1代表已删除) */ private Integer delFlag; }

权限类

package com.jt.pojo; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.fasterxml.jackson.annotation.JsonInclude; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; import java.util.Date; /** * 菜单表(Menu)实体类 * * @author makejava * @since 2021-11-24 15:30:08 */ @TableName(value="sys_menu") @Data @AllArgsConstructor @NoArgsConstructor @JsonInclude(JsonInclude.Include.NON_NULL) public class Menu implements Serializable { private static final long serialVersionUID = -54979041104113736L; @TableId private Long id; /** * 菜单名 */ private String menuName; /** * 路由地址 */ private String path; /** * 组件路径 */ private String component; /** * 菜单状态(0显示 1隐藏) */ private String visible; /** * 菜单状态(0正常 1停用) */ private String status; /** * 权限标识 */ private String perms; /** * 菜单图标 */ private String icon; private Long createBy; private Date createTime; private Long updateBy; private Date updateTime; /** * 是否删除(0未删除 1已删除) */ private Integer delFlag; /** * 备注 */ private String remark; }

SysResult类

package com.jt.vo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; import java.io.Serializable; @Data @Accessors(chain = true) @NoArgsConstructor @AllArgsConstructor public class SysResult implements Serializable { private Integer status; //200业务执行成功 201业务执行失败 private String msg; //服务器的提示信息 private Object data; //封装后台返回值 public static SysResult fail(){ return new SysResult(201,"业务执行失败",null); } public static SysResult success(){ return new SysResult(200,"业务执行成功",null); } //服务器返回业务数据 public static SysResult success(Object data){ return new SysResult(200,"业务执行成功",data); } public static SysResult success(String msg,Object data){ return new SysResult(200,msg,data); } }

WebUtils工具类

package com.jt.util; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * 往响应当中写入数据的工具类 */ public class WebUtils { /** * 将字符串渲染到客户端 * * @param response 渲染对象 * @param string 待渲染的字符串 * @return null */ public static String renderString(HttpServletResponse response, String string) { try { response.setStatus(200); response.setContentType("application/json"); response.setCharacterEncoding("utf-8"); response.getWriter().print(string); } catch (IOException e) { e.printStackTrace(); } return null; } }

二:实现UserDetailsService类,进行实现自己数据库获取用户信息和权限

创建Mapper,编译xml进行获取用户的信息和权限:

UserMapper,使用Mybatis-plus

@Mapper public interface UserMapper extends BaseMapper { }

MenuMapper

@Mapper public interface MenuMapper extends BaseMapper { List selectPermsByUserId(String userId); }

MenuMapper.xml

SELECT DISTINCT m.`perms` FROM sys_user_role ur LEFT JOIN `sys_role` r ON ur.`role_id` = r.`id` LEFT JOIN `sys_role_menu` rm ON ur.`role_id` = rm.`role_id` LEFT JOIN `sys_menu` m ON m.`id` = rm.`menu_id` WHERE user_id = #{userId} AND r.`status` = 0 AND m.`status` = 0

实现UserDetails,用此对象封装用户信息和权限

package com.jt.pojo; import com.alibaba.fastjson.annotation.JSONField; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import java.util.ArrayList; import java.util.Collection; import java.util.List; /** * 此方法实现的是UserServiceImpl 中的对象 封装了用户的信息 */ @Data @NoArgsConstructor public class LoginUser implements UserDetails { private User user; public LoginUser(User user, List permissions) { this.user = user; this.permissions = permissions; } private List permissions; @JSONField(serialize = false) //因为下面的泛型序列化可能会出错,所有用此注解让他不进行序列化 private List authorities;//方便下面调用进行创建静态的 @Override //此方法是获取权限信息的 所以要进行重写 public Collection


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3